<?php

/**
 * 图片合成类
 * Class ImageMergeLib
 * 所有方法参数中的x,y表示相对于背景图片bg_image的坐标
 * @package App\Libraries
 */
class ImageMergeLib
{
    public $path; //输出图片的目录
    public $filename; //输出图片的名字，不包含后缀
    public $bg_image; //背景图片
    public $image; //合成图片数组数据
    public $text; //合成图片文字数据

    /**
     * 设置输出图片的目录
     * @param $path
     */
    public function setPath($path) {
        $this->path = $path;
    }

    /**
     * 设置输出图片的名字，不包含后缀
     * @param $filename
     */
    public function setOutName($filename) {
        $this->filename = $filename;
    }

    /**
     * 设置背景图片
     * @param $bg_image
     * @param null $w 宽
     * @param null $h 高
     * @throws \Exception
     */
    public function setBgImage($bg_image, $w = null, $h = null) {
        $source = $this->loadImage($bg_image);
        $w = $w === null ? imagesx($source) : $w;
        $h = $h === null ? imagesy($source) : $h;
        $this->bg_image = [
            'source' => imagecreatefromjpeg($bg_image),
            'w' => $w,
            'h' => $h,
            'ext' => pathinfo($bg_image, PATHINFO_EXTENSION),
        ];
    }

    /**
     * 添加合成图片元素
     * @param $image
     * @param int $x 相对于
     * @param int $y
     * @param null $w
     * @param null $h
     * @param bool $circle
     * @throws \Exception
     */
    public function addSrcImage($image, $x = 0, $y = 0, $w = null, $h = null, $circle = false) {
        if($w && $h) {
            //裁剪
            $source = $this->resizeImage($image, $w, $h, $circle);
        } else {
            $source = $this->loadImage($image);
        }
        $w = imagesx($source);
        $h = imagesy($source);

        $this->image[] = [
            'source' => $source,
            'x' => $x,
            'y' => $y,
            'w' => $w,
            'h' => $h,
        ];
    }

    /**
     * 添加纯色背景
     * @param int $x
     * @param int $y
     * @param $w
     * @param $h
     * @param null $color
     */
    public function addPureImage($x = 0, $y = 0, $w, $h, $color = null) {
        $im = imagecreate($w, $h);
        $color = $color??imagecolorallocate($im, 255, 255, 255);
        imagefill($im, 0, 0, $color);
        $this->image[] = [
            'source' => $im,
            'x' => $x,
            'y' => $y,
            'w' => $w,
            'h' => $h,
        ];
    }

    /**
     * 添加文字
     * @param $str 文字内容
     * @param int $x
     * @param int $y
     * @param int $size 字体大小
     * @param null $color 颜色imagecolorallocatealpha资源
     * @param int $offset 默认高度偏移，因为文字坐标以左下角为准
     */
    public function addText($str, $x = 0, $y = 0, $size = 14, $color = null, $offset = 20) {
        $color = $color??imagecolorallocatealpha($this->bg_image['source'],0,0,0,50);
        $this->text[] = [
            'str' => $str,
            'x' => $x,
            'y' => $y + $offset,
            'size' => $size,
            'color' => $color
        ];
    }


    /**
     * 合并
     */
    public function merge() {
        if(!empty($this->image)) {
            foreach ($this->image as $v) {
                imagecopy(
                    $this->bg_image['source'],
                    $v['source'],
                    $v['x'],
                    $v['y'],
                    0,
                    0,
                    $v['w'],
                    $v['h']
                );
            }
        }

        if(!empty($this->text)) {
            foreach ($this->text as $v) {
                //imagestring($this->bg_image['source'],5,$v['x'],$v['y'],$v['str'],$v['color']);
                imagettftext(
                    $this->bg_image['source'], $v['size'], 0, $v['x'], $v['y'], $v['color'],
                    __DIR__.'/ttf/yaheiInconsolata.ttf', mb_convert_encoding($v['str'], "html-entities", "utf-8"));
            }
        }

        imagejpeg($this->bg_image['source'], $this->path . '/' . $this->filename . '.'. $this->bg_image['ext']);
    }

    /**
     * 根据图片格式载入图片资源
     * @param $im
     * @return resource
     * @throws \Exception
     */
    public function loadImage($im) {
        $img = getimagesize($im);
        switch ($img[2]) {
            case 1:
                $im = @imagecreatefromgif($im);
                break;
            case 2:
                $im = @imagecreatefromjpeg($im);
                break;
            case 3:
                $im = @imagecreatefrompng($im);
                break;
            default:
                throw  new \Exception('image format error');
                break;
        }
        return $im;
    }

    /**
     * 裁剪图片
     * @param $im
     * @param $maxwidth
     * @param $maxheight
     * @param bool $circle 是否需要裁剪为圆形
     * @return resource
     * @throws \Exception
     */
    function resizeImage($im, $maxwidth, $maxheight, $circle = false) {
        $im = $this->loadImage($im);
        $pic_width = imagesx($im);
        $pic_height = imagesy($im);
        $resizewidth_tag = false;
        $resizeheight_tag = false;
        if (($maxwidth && $pic_width > $maxwidth) || ($maxheight && $pic_height > $maxheight)) {
            if ($maxwidth && $pic_width > $maxwidth) {
                $widthratio = $maxwidth / $pic_width;
                $resizewidth_tag = true;
            }

            if ($maxheight && $pic_height > $maxheight) {
                $heightratio = $maxheight / $pic_height;
                $resizeheight_tag = true;
            }

            if ($resizewidth_tag && $resizeheight_tag) {
                if ($widthratio < $heightratio)
                    $ratio = $widthratio;
                else
                    $ratio = $heightratio;
            }

            if ($resizewidth_tag && !$resizeheight_tag)
                $ratio = $widthratio;
            if ($resizeheight_tag && !$resizewidth_tag)
                $ratio = $heightratio;
            $newwidth = $pic_width * $ratio;
            $newheight = $pic_height * $ratio;

            if (function_exists("imagecopyresampled")) {
                $newim = imagecreatetruecolor($newwidth, $newheight);
                imagecopyresampled($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $pic_width, $pic_height);
            } else {
                $newim = imagecreate($newwidth, $newheight);
                imagecopyresized($newim, $im, 0, 0, 0, 0, $newwidth, $newheight, $pic_width, $pic_height);
            }
            if($circle) {
                $img = imagecreatetruecolor($maxwidth, $maxheight);
                imagesavealpha($img, true);
                //拾取一个完全透明的颜色,最后一个参数127为全透明
                $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
                imagefill($img, 0, 0, $bg);
                $r = floor($maxwidth / 2); //圆半径
                $new_w = imagesx($newim);
                $new_h = imagesy($newim);
                for ($x = 0; $x < $new_w; $x++) {
                    for ($y = 0; $y < $new_h; $y++) {
                        $rgbColor = imagecolorat($newim, $x, $y);
                        if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                            imagesetpixel($img, $x, $y, $rgbColor);
                        }
                    }
                }
                return  $img;
            }
            return $newim;
        }
        return $im;
    }


}
